package be.ac.ua.comp.projectGPT.auctions;

//~--- non-JDK imports --------------------------------------------------------

import be.ua.ac.comp.projectGPT.auctionPolicies.AuctionPolicy;
import be.ac.ua.comp.projectGPT.auctioneers.Auctioneer;
import be.ac.ua.comp.projectGPT.biddingAgents.BiddingAgent;
import be.ac.ua.comp.projectGPT.exceptions.DuplicateException;
import be.ac.ua.comp.projectGPT.exceptions.InitializationException;
import be.ac.ua.comp.projectGPT.players.Provider;
import be.ac.ua.comp.projectGPT.types.Type;

import org.slf4j.*;

//~--- JDK imports ------------------------------------------------------------

import java.util.Vector;

/**
 *
 * @author Admin
 */
public abstract class Auction<T extends Type> implements Runnable {
    protected boolean       initialized = false;
    protected final Logger    logger      = LoggerFactory.getLogger(this.getClass().getSimpleName());
    long                    startingBid = 0;
    Auctioneer<T>           auctioneer;
    Vector<BiddingAgent<T>> biddingAgents;
    int                     biddingRound = 0;
    int                     biddings = 0;
    AuctionPolicy           policy;
    Provider provider;

    public Auction() {
        this(null);
    }

    public Auction(Auctioneer<T> auctioneer) {
        this.biddingAgents = new Vector<BiddingAgent<T>>();
        this.auctioneer    = auctioneer;
        initialized        = false;
    }

    public void setProvider(Provider provider) {
        this.provider = provider;
        auctioneer.setProvider(provider);
    }



    public Provider getProvider() {
        return provider;
    }

    public long getStartingBid() {
        return startingBid;
    }

    public void setStartingBid(long startingBid) {
        this.startingBid = startingBid;
    }

    public int getBiddings() throws InitializationException {
        if (!initialized) {
            throw new InitializationException();
        }
        return biddings;
       
    }

    public int getBiddingRound() {
        return biddingRound;
    }

    public void setPolicy(AuctionPolicy policy) {
        this.policy = policy;
        initialized = (auctioneer != null);
    }

    public void addBiddingAgent(BiddingAgent<T> agent) throws DuplicateException {
        if (biddingAgents.contains(agent)) {
            throw new DuplicateException(agent.getName());
        }

        logger.info("Adding bidding agent " + agent.getName());
        biddingAgents.add(agent);
        auctioneer.addBiddingAgent(agent);
    }

    public void setAuctioneer(Auctioneer<T> auctioneer) {
        this.auctioneer = auctioneer;
        initialized     = (policy != null);
    }

    public Auctioneer<T> getAuctioneer() throws InitializationException {
        if (auctioneer == null) {
            throw new InitializationException("No auctioneer");
        }
        return auctioneer;
    }

    public void resetBiddings() {
        biddings = 0;
    }

    public void newBidding() {
        biddings++;
    }
}
